package com.yutons.encrypt.interceptor;

import com.yutons.encrypt.config.MpEncryptProperties;
import com.yutons.encrypt.cryptor.IMpEncrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.util.CollectionUtils;

import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;

/**
 * @Title 返回值插件ResultSetInterceptor
 * @Author yutons
 * @Date 2024-07-25 13:16
 * @Desc 切入mybatis设置参数时对敏感数据进行解密
 * Intercepts注解
 * 使用mybatis插件时需要定义签名
 * type标识需要切入的Handler
 * method表示要要切入的方法
 */
@Slf4j
@Intercepts({
	@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class MpEncryptResultSetInterceptor implements Interceptor {
	private final IMpEncrypt customEncryptor;
	private final MpEncryptProperties properties;

	public MpEncryptResultSetInterceptor(IMpEncrypt customEncryptor, MpEncryptProperties properties) {
		this.customEncryptor = customEncryptor;
		this.properties = properties;
	}

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 取出查询结果
		Object resultObject = invocation.proceed();
		if (Objects.isNull(resultObject)) {
			return null;
		}
		if (properties.getEnabled()) {
			// 基于selectList
			if (resultObject instanceof ArrayList) {
				ArrayList<Object> resultList = (ArrayList<Object>) resultObject;
				if (!CollectionUtils.isEmpty(resultList)) {
					for (Object result : resultList) {
						if (result != null) {
							// 逐一解密
							customEncryptor.decrypt(result);
						}
					}
				}
			} else {
				// 基于selectOne
				customEncryptor.decrypt(resultObject);
			}
		}
		return resultObject;
	}

	@Override
	public Object plugin(Object target) {
//		return Interceptor.super.plugin(target);
		return target instanceof ResultSetHandler ? Plugin.wrap(target, this) : target;
	}

	@Override
	public void setProperties(Properties properties) {
	}
}
